package com.mendmix.tutorial.controller;

import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.mendmix.common.annotation.ApiMetadata;
import com.mendmix.common.constants.PermissionLevel;
import com.mendmix.common.model.WrapperResponse;
import com.mendmix.common.util.DigestUtils;
import com.mendmix.common.util.ParameterUtils;
import com.mendmix.cos.CUploadObject;
import com.mendmix.cos.CUploadResult;
import com.mendmix.cos.CosProvider;
import com.mendmix.gateway.GatewayConstants;
import com.mendmix.gateway.filter.pre.SignatureRequestHandler;
import com.mendmix.gateway.model.OpenApiConfig;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping(GatewayConstants.PATH_PREFIX)
public class CommonController {

	@Autowired(required = false)
	private CosProvider cosProvider;
	
	@PostMapping("open/signature")
	@ApiMetadata(actionName = "生成签名",permissionLevel = PermissionLevel.Anonymous,actionLog = false)
	public WrapperResponse<Map<String, String>> generateSignature(ServerHttpRequest request,@RequestBody Map<String, Object> param){
		Map<String, String> result = new HashMap<>(2);
		
		String clientId = request.getQueryParams().getFirst("clientId");
		
		OpenApiConfig openApiConfig = SignatureRequestHandler.getOpenApiConfig(clientId);

		String timestamp = String.valueOf(System.currentTimeMillis());
		result.put("timestamp", timestamp);
		
		String signBaseString = StringUtils.trimToEmpty(ParameterUtils.mapToQueryParams(param)) + timestamp + openApiConfig.getClientSecret();
		String sign = DigestUtils.md5(signBaseString);
		result.put("sign", sign);
        
		return new WrapperResponse<>(result);
	}
	
	@PostMapping("file/upload")
    @ResponseBody
    @ApiMetadata(actionName = "上传文件",permissionLevel = PermissionLevel.LoginRequired,actionLog = false)
	public Mono<WrapperResponse<CUploadResult>> upload(ServerHttpRequest request,@RequestPart("file") FilePart filePart) {
		
		Flux<DataBuffer> bufferFlux = filePart.content();
		Mono<WrapperResponse<CUploadResult>> mono;
		mono = bufferFlux.map(dataBuffer -> dataBuffer.asInputStream()) //
				.reduce(SequenceInputStream::new) //
				.flatMap(inputStream -> {
					try {
						byte[] bytes = IOUtils.toByteArray(inputStream);
						CUploadResult result = cosProvider.upload(new CUploadObject(bytes, null));
						return Mono.just(new WrapperResponse<>(result));
					} catch (IOException e) {
						e.printStackTrace();
						return Mono.just(new WrapperResponse<>(500,"上传失败"));
					}
				});
		return mono;
	}
}
